"""
-------------------------------
- File_Name: menus.py
- Date: 2025/3/7
- Author: yangzhide
- Email: xxzjyzd@126.com
- Description: 系统菜单
-------------------------------
"""

from fastapi import APIRouter, Depends, Path, Body, Query, HTTPException
from tortoise.exceptions import IntegrityError

from app.schemas import BaseResponse, BaseResponseExtra
from app.schemas.system.menus import *
from app.models import Menu, Button
from app.core.security import get_current_user
from app.utils.ormUtil import OrmCRUD
from app.utils.responseUtil import ResponseUtil
from app.core.ctx import CTX_USER
from app.utils.system import delete_menu_and_children, build_menu_tree

router = APIRouter(prefix="/systemManage", dependencies=[Depends(get_current_user)])
tags = ["系统菜单信息"]
description = "系统菜单信息相关接口"


@router.post("/menus", summary="创建菜单信息", response_model=BaseResponse[SystemManageMenuOut])
async def _(menu_in: SystemManageMenuCreate):
    """系统管理-菜单创建"""

    # 更新创建人
    menu_in.create_by = CTX_USER.get().user_name
    menu_dict = await OrmCRUD(Menu).add(**menu_in.model_dump())

    # 新增按钮
    add_button = [Button(menu_id=menu_dict["id"], button_code=b.code, button_desc=b.desc) for b in menu_in.buttons]
    await Button.bulk_create(add_button)

    # 序列化更新按钮列表
    menu_dict["buttons"] = menu_in.buttons
    return ResponseUtil.success_response(data=menu_dict, msg=f"创建菜单成功")


@router.delete("/menus/{id}", summary="删除菜单", response_model=BaseResponse[dict])
async def delete_menu(_id: int | str = Path(alias="id", description="菜单id")):
    """系统管理-菜单删除"""
    await delete_menu_and_children(menu_id=_id)
    return ResponseUtil.success_response(data=[], msg="删除菜单成功")

@router.delete("/menus", summary="批量删除菜单", response_model=BaseResponse[dict])
async def _(menu_ids: str = Query(alias="ids", description="菜单id列表")):
    """系统管理-批量删除菜单"""
    ids_list = menu_ids.split(",")
    for menu_id in ids_list:
        # 删除菜单
        await delete_menu(menu_id)
    return ResponseUtil.success_response(data={}, msg="批量删除菜单成功")


@router.patch("/menus/{id}", summary="更新菜单", response_model=BaseResponse[SystemManageMenuOut])
async def _(
        _id: int | str = Path(alias="id"),
        menu_update: SystemManageMenuUpdate = Body()
):
    update_dict = menu_update.model_dump()

    # 更新者
    menu_update.update_by = CTX_USER.get().user_name
    # 更新菜单
    menu_dict = await  OrmCRUD(Menu).update(data=menu_update, id=_id)

    if menu_dict is None:
        raise HTTPException(status_code=404, detail=f"更新菜单不存在【id={_id}】")

    # 1. 全部删除所有按钮，这样保证按钮名称修改也同时更新
    await Button.filter(menu_id=_id).delete()
    # 2. 全部重新添加
    if update_dict["buttons"]:
        add_button = [Button(menu_id=_id, button_code=f["code"], button_desc=f["desc"]) for f in
                      update_dict["buttons"]]
        await Button.bulk_create(add_button)
    # 返回菜单按钮列表
    menu_dict["buttons"] = update_dict["buttons"]
    return ResponseUtil.success_response(data=menu_dict, msg="更新菜单成功")


@router.get("/getMenuList/v2", summary="查询所有菜单信息", response_model=BaseResponseExtra[SystemManageMenuOutList])
@router.get("/menus", summary="查询所有菜单信息", response_model=BaseResponseExtra[SystemManageMenuOutList])
async def _(
        current: int = Query(default=1, ge=1, description="页码"),
        size: int = Query(default=100, ge=100, description="每页数量"),
):
    """系统管理-菜单列表"""
    menus = await Menu.all().order_by("order")
    menus_list = await build_menu_tree(menus)  # 菜单queryset
    total, data = await OrmCRUD(Menu).filter(current, size, parent_id=0)  # data 菜单字典
    return ResponseUtil.success_response_extra(total, current, size, data=menus_list, msg="查询菜单成功")


@router.get("/menus/{id}", summary="查询单个菜单信息", response_model=BaseResponse[SystemManageMenuOut])
async def _(id: int | str = Path(description="菜单id")):
    menu_obj = await OrmCRUD(Menu).get_or_none(id)
    if menu_obj is None:
        raise HTTPException(status_code=404, detail=f"查询菜单对象【id={id}】不存在")

    # 菜单按钮
    buttons_list = await Button.filter(menu_id=menu_obj["id"]).values("button_code", "button_desc")
    menu_obj["buttons"] = buttons_list
    return ResponseUtil.success_response(data=menu_obj, msg=f"查询菜单成功")


@router.get("/getAllPages", summary="获取所有页面组件", response_model=BaseResponse[RoleMenuHome])
async def _():
    menus = await Menu.filter(constant=False).order_by("order").values("menu_name","route_name")
    # data = [menu.route_name for menu in menus]
    # data = [menu.menu_name for menu in menus]
    return ResponseUtil.success_response(data=menus, msg="获取所有页面组件")


@router.get("/getMenuTree", summary="查看菜单树")
async def _():
    menus = await Menu.filter(constant=False,status="1").order_by("order")

    # 递归生成菜单
    menu_tree = await build_menu_tree(menus, simple=True)
    return {"code": "200", "data": menu_tree, "msg": "查询菜单树成功"}
